#include "gtest/gtest.h"

#include "rocksdb/status.h"
#include "rocksdb/file_system.h"


using namespace rocksdb;
TEST(FileSystemTest, writableFile){
    auto fs = rocksdb::FileSystem::Default();
    ASSERT_TRUE(fs != nullptr);

    std::unique_ptr<FSWritableFile> file;
    const std::string fname = "hello.db";
    auto s = fs->NewWritableFile(fname, FileOptions(), &file, nullptr);
    ASSERT_TRUE(s.ok());

    s = file->Append(Slice("hello"), IOOptions(), nullptr);
    ASSERT_TRUE(s.ok());
}

TEST(FileSystemTest, readableFile){
    auto fs = rocksdb::FileSystem::Default();
    ASSERT_TRUE(fs != nullptr);

    std::unique_ptr<FSSequentialFile> file;
    const std::string fname = "hello.db";
    auto s = fs->NewSequentialFile(fname, FileOptions(), &file, nullptr);
    ASSERT_TRUE(s.ok());

    char buf[1024];
    Slice result;
    s = file->Read(1024, IOOptions(), &result, buf, nullptr);
    ASSERT_TRUE(s.ok());
}
TEST(FileSystemTest, fsLoad){
    std::shared_ptr<FileSystem> fs;
    auto s = FileSystem::Load("Posix File System", &fs);
    ASSERT_FALSE(s.ok());
}


struct Block{
    Block(): data(1) {}
    ~Block(){}
    int data;
};
class CacheRocksdbImp {
public:
    explicit CacheRocksdbImp(uint64_t capacity ) 
    : capacity(capacity) 
    {
    }
    virtual ~CacheRocksdbImp(){}
    virtual Block * lookup(const rocksdb::Slice & key){
        return nullptr;
    }
    virtual Status insert(const rocksdb::Slice & key, Block * value){
        return Status::OK();
    }
    virtual void erase(const rocksdb::Slice & key){
    }
private:
    uint64_t capacity;
};

TEST(CacheTest, use){
    CacheRocksdbImp cache(1024*1024);

    rocksdb::Slice key = "stream0";
    Block * blk = new Block();
    cache.insert(key,blk);
    ASSERT_TRUE(blk != cache.lookup(key));

    cache.erase(key);
    ASSERT_EQ(nullptr, cache.lookup(key));
    delete blk;
}
